package com.hellobike.haxing.modules.order.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hellobike.haxing.common.system.query.QueryGenerator;

import com.hellobike.haxing.common.system.vo.LoginUser;
import com.hellobike.haxing.common.util.DateUtils;
import com.hellobike.haxing.common.util.RedisUtil;
import com.hellobike.haxing.common.vo.Result;
import com.hellobike.haxing.common.vo.ResultCode;
import com.hellobike.haxing.modules.order.constant.OrderConstants;
import com.hellobike.haxing.modules.order.entity.*;
import com.hellobike.haxing.modules.order.mapper.OrderAftersaleMapper;
import com.hellobike.haxing.modules.order.mapper.OrderDetailMapper;
import com.hellobike.haxing.modules.order.mapper.OrderGroupMapper;
import com.hellobike.haxing.modules.order.mapper.OrderMapper;
import com.hellobike.haxing.modules.order.send.OrderCancelBSend;
import com.hellobike.haxing.modules.order.send.OrderCloseCSend;
import com.hellobike.haxing.modules.order.service.*;
import com.hellobike.haxing.modules.product.mapper.ProductMapper;
import com.hellobike.haxing.modules.purchase.dto.TPurchaseProDto;
import com.hellobike.haxing.modules.purchase.service.ITPurchaseProService;
import com.hellobike.haxing.modules.shop.constant.ShopConstants;
import com.hellobike.haxing.modules.shop.entity.Shop;
import com.hellobike.haxing.modules.shop.service.IShopAccountService;
import com.hellobike.haxing.modules.shop.service.IShopService;
import com.hellobike.haxing.modules.wms.entity.WarehouseShop;
import com.hellobike.haxing.modules.wms.mapper.WarehouseShopMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 订单信息
 * @Author: haxing-boot
 * @Date: 2020-02-08
 * @Version: V1.0
 */
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IOrderDetailService orderDetailService;
    @Autowired
    private IOrderAftersaleService orderAftersaleService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private IOrderRefundService orderRefundService;
    @Autowired
    private IOrderBService orderBService;
    @Autowired
    private OrderCancelBSend orderCancelBSend;
    @Autowired
    private IOrderCouponService orderCouponService;
    @Autowired
    private IOrderTimeConfigService orderTimeConfigService;
    @Autowired
    private ITPurchaseProService purchaseProService;
    @Autowired
    private IOrderAftersaleDetailService orderAftersaleDetailService;
    @Autowired
    private IShopAccountService shopAccountService;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private OrderCloseCSend orderCloseCSend;
    @Autowired
    private OrderAftersaleMapper orderAftersaleMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private WarehouseShopMapper warehouseShopMapper;
    @Autowired
    private OrderGroupMapper orderGroupMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public IPage<Order> queryPage(Order order, Page<Order> page, Map<String, String[]> parameterMap) {
        QueryWrapper<Order> queryWrapper = QueryGenerator.initQueryWrapper(order, parameterMap);
        return orderMapper.queryPage(page, queryWrapper);
    }

    @Override
    public Order getOrderById(Long id) {
        Order order = orderMapper.getOrderById(id);
        //查询订单明细
        List<OrderDetail> detailList = orderDetailService.queryDetailList(order.getId());
        order.setDetailList(detailList);
        if (OrderConstants.ORDER_STATUS_6.equals(order.getStatus()) || OrderConstants.ORDER_STATUS_10.equals(order.getStatus()) || OrderConstants.ORDER_STATUS_14.equals(order.getStatus())
                || OrderConstants.ORDER_STATUS_15.equals(order.getStatus())) {
            List<OrderAftersale> aftersaleList = orderAftersaleService.queryList(order.getId());
            order.setAftersaleList(aftersaleList);
        }
        Shop shop = shopService.getById(order.getShopId());
        Shop leader = shopService.getById(order.getLeaderId());
        order.setAddress(shop.getAddress());
        List<OrderShop> orderShopList = new ArrayList<>();
        List<OrderCoupon> couponList = orderCouponService.queryList(id);
        order.setCouponList(couponList);
        for (OrderDetail detail : detailList) {
            /**
             * 一级分佣金
             */
            OrderShop orderShop = new OrderShop();
            BeanUtils.copyProperties(shop, orderShop);
            //提现=佣金
            orderShop.setTitle(detail.getTitle());
            BigDecimal withdrewAmount = detail.getShopAmount();
            orderShop.setWithdrewAmount(withdrewAmount);
            orderShopList.add(orderShop);
            /**
             * 二级分佣
             */
            if (leader != null) {
                OrderShop orderShop2 = new OrderShop();
                orderShop2.setCommissionType(2);
                BeanUtils.copyProperties(leader, orderShop2);
                //提现=佣金
                orderShop2.setTitle(detail.getTitle());
                BigDecimal withdrewAmount2 = detail.getLeaderAmount();
                orderShop2.setWithdrewAmount(withdrewAmount2);
                orderShopList.add(orderShop2);
            }
        }
//        for (OrderShop ordershop : orderShopList) {
//            ordershop.setTotalWithdrewAmount(totalWithdrewAmount);
//        }
        order.setShopList(orderShopList);
        return order;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePayTimeOutCloseOrder() {
        long millis = DateUtils.getDate().getTime() - orderTimeConfigService.getPayCloseTimeConfig();
        Date date = DateUtils.getDate(millis);
        List<Long> orderIdsList = orderMapper.queryPayTimeOutCloseOrder(date);
        orderMapper.updatePayTimeOutCloseOrder(date);
        for (Long id : orderIdsList) {
            orderCloseCSend.sendOrderClose(id);
        }
    }

    /**
     * 取消订单到结单时间，未审核，默认都审核不通过
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateCancelTimeOutCloseOrder() {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        // 查询审核的订单
        queryWrapper.lambda().eq(Order::getDeleted, OrderConstants.DEL_FLAG_0);
        queryWrapper.lambda().eq(Order::getStatus, OrderConstants.ORDER_STATUS_30);
        queryWrapper.lambda().le(Order::getSuccessTime, new Date());
        List<Order> lists = super.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(lists)) {
            //更新订单状态
            for (Order order : lists) {
                order.setStatus(OrderConstants.ORDER_STATUS_3); // 订单状态变更为审核之前的支付待提货状态
                order.setApproveStatus(OrderConstants.APPROVE_STATUS_NO); // 标识订单取消审核状态为审核不通过
                order.setApproveTime(DateUtils.getDate()); // 审核时间
                orderMapper.updateById(order);
            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSyncPurchase(Long id, Integer type) throws RuntimeException {
        Order order = orderMapper.getById(id);
        if (DateUtil.beginOfDay(order.getCreateTime()).before(DateUtil.offsetDay(new Date(), -1))) {
            log.error("时间太久的订单-=--》{}", JSON.toJSONString(order));
            return;
        }
        List<OrderDetail> detailList = orderDetailMapper.queryOrderDetail(order.getId());
        Set<Long> productIds = detailList.stream().map(e -> e.getProductId()).collect(Collectors.toSet());
        //查询非常备货
        List<Long> list = productMapper.queryVeryProductIds(productIds);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (OrderDetail detail : detailList) {
            log.info("同步订单到采购单过滤常备商品=orderId={}=list={}=spuId={}=skuId={}=", id, JSON.toJSONString(list), detail.getProductId(), detail.getSkuId());
            if (!list.contains(detail.getProductId())) {
                continue;
            }
            log.info("同步订单到采购单开始=orderId={}=list={}=spuId={}=skuId={}=", id, JSON.toJSONString(list), detail.getProductId(), detail.getSkuId());
            TPurchaseProDto dto = new TPurchaseProDto();
            dto.setType(type);
            dto.setSkuId(detail.getSkuId());
            dto.setPurchaseVolume(detail.getNum());
            dto.setOrderCode(order.getBillNo());
            dto.setOrderTime(order.getSuccessTime());
            WarehouseShop warehouseShop = warehouseShopMapper.selectOne(new QueryWrapper<WarehouseShop>()
                    .lambda().eq(WarehouseShop::getShopId, order.getShopId()).eq(WarehouseShop::getDeleted, 0)
                    .last("limit 1"));
            dto.setWarehouseId(warehouseShop.getWarehouseId());

            Result<?> result = purchaseProService.syncProFromOrder(dto);
            if (!result.isSuccess()) {
                log.error("同步订单到采购单失败==orderId={}==dto={}=返回消息结果={}=", id, JSON.toJSONString(dto), result.getMessage());
                throw new RuntimeException("同步采购单失败");
            }
            log.info("同步订单到采购单成功结束==orderId={}==dto={}=返回消息结果={}=", id, JSON.toJSONString(dto), result.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateShopCommission() {
        Page<Order> page = new Page<>(1, 1000);
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Order::getStatus, OrderConstants.ORDER_STATUS_6).isNull(Order::getShopMissTime);
        IPage<Order> pageResult = super.page(page, queryWrapper);
        List<Order> lists = pageResult.getRecords();
        Map<Long, BigDecimal> shopAmountMap = new HashMap<>();
        List<Long> orderIds = new ArrayList<>();
        //查询明细售后情况
        for (Order order : lists) {
            BigDecimal totalShopAmount = BigDecimal.ZERO;
            BigDecimal leadAmount = BigDecimal.ZERO;
            List<OrderDetail> detailList = orderDetailService.queryDetailList(order.getId());
            // 计算佣金
            for (OrderDetail detail : detailList) {
                BigDecimal afterShopAmount = getShopAmount(detail.getId());
                BigDecimal shopAmount = detail.getShopAmount().subtract(afterShopAmount);
                if (shopAmount.compareTo(BigDecimal.ZERO) < 0) {
                    log.info("佣金为负数设置为0元=订单明细ID=orderDetailId=={}==shopAmount={}=afterShopAmount={}=", detail.getId(), shopAmount, afterShopAmount);
                    shopAmount = BigDecimal.ZERO;
                }
                leadAmount = leadAmount.add(detail.getLeaderAmount());
                log.info("团长返佣金=shopId={}=订单明细ID=orderDetailId=={}==明细佣金=shopAmount=={}=afterShopAmount={}=", order.getId(), detail.getId(), shopAmount, afterShopAmount);
                totalShopAmount = totalShopAmount.add(shopAmount);
            }
            /**
             * 计算团长分佣
             */
            if (shopAmountMap.containsKey(order.getShopId())) {
                shopAmountMap.put(order.getShopId(), shopAmountMap.get(order.getShopId()).add(totalShopAmount));
            } else {
                shopAmountMap.put(order.getShopId(), totalShopAmount);
            }
            /**
             * 计算一级领导分佣
             */
            if (shopAmountMap.containsKey(order.getLeaderId())) {
                shopAmountMap.put(order.getLeaderId(), shopAmountMap.get(order.getLeaderId()).add(leadAmount));
            } else {
                shopAmountMap.put(order.getLeaderId(), leadAmount);
            }
            orderIds.add(order.getId());
        }
        if (!shopAmountMap.isEmpty() && CollectionUtils.isNotEmpty(orderIds)) {
            //返团长佣金
            shopAmountMap.forEach((k, v) -> {
                log.info("===团长返佣金本次总金额==shopId={}==总金额=={}=", k, v);
                if (v.compareTo(BigDecimal.ZERO) > 0)
                    shopAccountService.addIncome(k, v, ShopConstants.ACCOUNT_STATUS_1, "销售提成");
            });
            //更新订单已返佣金的时间
            orderMapper.updateShopCommission(orderIds);
        }
    }

    @Override
    public int countOrderUserId(Long userId) {
        return orderMapper.countOrderUserId(userId);
    }

    /**
     * 订单取消:审核通过
     *
     * @param orderId 订单ID
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<?> approveCancelOrder(Long orderId) throws Exception {
        //获取订单信息
        Order order = orderMapper.getById(orderId);
        if (order == null) {
            log.error("订单取消:审核失败,订单不存在！==orderId={}", orderId);
            return Result.error("审核失败,订单不存在");
        }
        if (OrderConstants.ORDER_STATUS_2.equals(order.getStatus())) {
            log.error("订单取消:审核失败，订单已取消！==orderId={}", orderId);
            return Result.error("审核失败,订单已取消");
        }
        //未支付和已支付订单才允许取消
//        if (!OrderConstants.ORDER_STATUS_1.equals(order.getStatus()) && !OrderConstants.ORDER_STATUS_3.equals(order.getStatus())) {
//            log.error("订单取消:审核失败，未支付和待提货状态下才允许取消！==orderId={}",orderId);
//            return false;
//        }
        if (!OrderConstants.ORDER_STATUS_30.equals(order.getStatus())) {
            log.error("订单取消:审核失败，审核中才允许取消！==orderId={}", orderId);
            return Result.error("审核失败,审核中才允许取消");
        }
        if (OrderConstants.ORDER_PAY_1.equals(order.getIsPay())) {
            //判断是否未成团(未成团订单是否可取消)
            if (order.getSuccessTime() == null && OrderConstants.ORDER_BIZ_TYPE_3.equals(order.getType())) {
                log.error("订单取消:审核失败，拼团未成团订单不允许取消订单！==orderId={}", orderId);
                return Result.error("审核失败,拼团未成团订单不允许取消订单");
            }
//            /**
//             * 已支付
//             * 1、已付款在结单时间后不允许取消
//             * 2、可以取消时退款和退优惠券、退款
//             */
//            Date orderEndTime = orderTimeConfigService.getOrderEndTimeConfig();
//            Instant orderEndTimeInstant = orderEndTime.toInstant();
//            ZoneId orderEndTimeZone = ZoneId.systemDefault();
//            LocalDateTime localOrderEndDateTime = LocalDateTime.ofInstant(orderEndTimeInstant, orderEndTimeZone);
//            LocalTime localOrderEndTime = localOrderEndDateTime.toLocalTime();
//
//            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
//            String HMS = formatter.format(localOrderEndTime);
//
//            LocalDateTime localTime = LocalDateTime.now();
//
//            Date successTime = order.getSuccessTime();
//            Instant successTimeInstant = successTime.toInstant();
//            ZoneId successTimeZone = ZoneId.systemDefault();
//            LocalDateTime localSuccessDateTime = LocalDateTime.ofInstant(successTimeInstant, successTimeZone);
//
//            Duration duration = Duration.between(localTime, localSuccessDateTime);
//            long second = duration.getSeconds();
//            log.info("====支付取消订单==秒差={}===当前时间=localTime={}==结单时间={}={}", second, localTime, order.getSuccessTime(), order.getId());
//            if (second >= 0) {
            //发送退款信息
            orderRefundService.saveRefundAmount(order.getId(), order.getPayAmount(), order.getBillNo());
            orderCancelBSend.sendOrderCancel(order.getId());
//            } else {
//                log.error("订单取消:审核失败，{}结单后不允许取消订单！==orderId={}",HMS,orderId);
//                return Result.error(String.format("审核失败,%s结单后不允许取消订单",HMS));
//            }
        }
        order.setStatus(OrderConstants.ORDER_STATUS_2);
        orderCouponService.returnCoupon(order.getId());
        order.setCancelTime(DateUtils.getDate());
        order.setApproveStatus(OrderConstants.APPROVE_STATUS_YES); // 标识订单取消审核状态为审核不通过
        order.setApproveTime(DateUtils.getDate()); // 审核时间
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        order.setApprover(sysUser.getId());
        boolean flag = super.updateById(order);
        orderBService.updateCancel(order.getId());
        //拼团订单取消拼团未支付则移除拼团数据
        if (OrderConstants.ORDER_BIZ_TYPE_3.equals(order.getType()) && OrderConstants.ORDER_PAY_0.equals(order.getIsPay())) {
            orderGroupMapper.deleteOrderId(orderId, order.getUserId());
        }
        orderDetailService.returnOrderDetailStock(order.getId(), order.getShopId());
        return Result.ok("审核成功");
    }

    /**
     * 订单取消：审核不通过
     *
     * @param orderId
     * @return
     */
    @Override
    public boolean rejectCancelOrder(Long orderId) {
        //获取订单信息
        Order order = orderMapper.getById(orderId);
        if (order == null) {
            log.error("订单取消:审核失败,订单不存在！==orderId={}", orderId);
            return false;
        }
        if (!OrderConstants.ORDER_STATUS_30.equals(order.getStatus())) {
            log.error("订单取消:审核失败，审核中才允许取消！==orderId={}", orderId);
            return false;
        }
//        order.setStatus(order.getOriginStatus()); // 订单状态变更为审核之前的状态
        order.setStatus(OrderConstants.ORDER_STATUS_3); // 订单状态变更为审核之前的支付待提货状态
        order.setApproveStatus(OrderConstants.APPROVE_STATUS_NO); // 标识订单取消审核状态为审核不通过
        order.setApproveTime(DateUtils.getDate()); // 审核时间
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        order.setApprover(sysUser.getId());
        orderMapper.updateById(order);
        return true;

    }

    private BigDecimal getShopAmount(Long orderDetailId) {
        //查询售后金额
        OrderAftersale orderAftersale = orderAftersaleMapper.getAfterSuccess(orderDetailId);
        if (orderAftersale == null) {
            return BigDecimal.ZERO;
        }
        //查询明细售后情况
        List<OrderDetail> detailList = orderDetailMapper.queryAfterOrderDetail(orderAftersale.getId());
        // 计算佣金=（商品金额*数量-售后金额）* 提成率
        BigDecimal zAfterAmound = BigDecimal.ZERO;
        for (OrderDetail detail : detailList) {
            BigDecimal productAmount = detail.getProductAmount().subtract(detail.getCouponAmount());
            zAfterAmound = zAfterAmound.add(productAmount);
        }
        //计算比例
        BigDecimal rate = orderAftersale.getReturnAmount().divide(zAfterAmound, 2, BigDecimal.ROUND_HALF_UP);
        log.info("=售后扣除商品比例=rate={}==", rate);
        BigDecimal shopAmount = BigDecimal.ZERO;
        for (OrderDetail detail : detailList) {
            BigDecimal productAmount = detail.getProductAmount().subtract(detail.getCouponAmount()).multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP);
            BigDecimal commissionRate = detail.getCommissionRate().divide(new BigDecimal(100));
            shopAmount = productAmount.multiply(commissionRate).setScale(2, BigDecimal.ROUND_HALF_UP);
            if (orderDetailId.equals(detail.getId())) {
                log.info("=售后扣除商品佣金=productAmount=={}=commissionRate={}=shopAmount={}==skuId={}=productId={}=", productAmount, commissionRate, shopAmount, detail.getSkuId(), detail.getProductId());
                break;
            }
        }
        return shopAmount;
    }


}
